package com.rf.richfitwheel.dyn.business.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rf.richfitwheel.common.utils.R;
import com.rf.richfitwheel.common.utils.UuidUtil;
import com.rf.richfitwheel.dyn.business.entity.SysApiSendHis;
import com.rf.richfitwheel.dyn.business.mapper.SysApiSendHisMapper;
import com.rf.richfitwheel.dyn.business.service.SysApiSendHisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

/**
 * 接口调用历史表 服务层实现。
 *
 * @author richfitwheel
 * @since 2025-02-19
 */
@Service
public class SysApiSendHisServiceImpl extends ServiceImpl<SysApiSendHisMapper, SysApiSendHis> implements SysApiSendHisService {
    private static final Logger log = LoggerFactory.getLogger(SysApiSendHisServiceImpl.class);
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RestTemplate restTemplateOuter;
    @Resource
    private ObjectMapper serializingObjectMapper;
    /**
     * 调用接口
     *
     * @param url     地址
     * @param method  请求方式：post、get
     * @param apiType 接口类型:1-内部、2-外部
     * @param header  请求头
     * @param param   请求体
     */
    @Override
    public void exchangeApi(String url, String method, String apiType, String header, String param) {
        LocalDateTime localDateTime = LocalDateTime.now();
        SysApiSendHis his = new SysApiSendHis();
        his.setId(UuidUtil.get32UUID());
        his.setApiType(apiType);
        his.setApiUrl(url);
        his.setRequestMethod(method);
        his.setRequestHeader(header);
        his.setRequestParam(param);
        his.setCreateTime(localDateTime);
        his.setLastTime(localDateTime);
        his.setSendCount(1);

        if ("1".equals(apiType)) {
            //内部接口
            HttpEntity<String> entity = new HttpEntity<>(param);
            try {
                ResponseEntity<R> response = restTemplate.exchange(url, HttpMethod.valueOf(method), entity, R.class);
                if (response.getStatusCode().isError()) {
                    log.error(Objects.requireNonNull(response.getBody()).toString());
                    his.setSendStatus("0");
                }else {
                    if(Objects.requireNonNull(response.getBody()).getCode().equals("0")){
                        his.setSendStatus("1");
                    }else{
                        log.error(Objects.requireNonNull(response.getBody()).getMsg());
                        his.setSendStatus("0");
                    }
                }
            } catch (RestClientException e) {
                log.error(e.getMessage(), e);
                his.setSendStatus("0");
            }
        }else{
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setAll(serializingObjectMapper.readValue(header, new MyTypeReference()));
                HttpEntity<String> entity = new HttpEntity<>(param, headers);
                ResponseEntity<Object> exchange = restTemplateOuter.exchange(url, HttpMethod.valueOf(method), entity, Object.class);
                if (exchange.getStatusCode().isError()) {
                    log.error(Objects.requireNonNull(exchange.getBody()).toString());
                    his.setSendStatus("0");
                }else {
                    his.setSendStatus("1");
                }
            } catch (RestClientException e) {
                log.error(e.getMessage(), e);
                his.setSendStatus("0");
            } catch (JsonProcessingException e) {
                log.error("请求参数解析失败", e);
                his.setSendStatus("0");
            }
        }
        this.save(his);
    }

    private static class MyTypeReference extends TypeReference<Map<String, String>> {
    }
}
